package ac.il.technion.cs236635.project.core;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.log4j.Logger;

import ac.il.technion.cs236635.project.core.server.ServerJob;

public class JobsKeeper {

	private static final JobsKeeper _instance = new JobsKeeper( );
	
	private final List< ServerJob> jobs = new ArrayList< ServerJob>( );

	private final Map< Integer, Long> timeline = new HashMap< Integer, Long>( );
	
	private Logger log = Logger.getLogger( JobsKeeper.class);
	
	private int timeout = 2000;
	
	private JobsKeeper( ) {
		Properties properties = new Properties( );
		try {
			properties.load( JobsKeeper.class.getClassLoader().getResourceAsStream("client.properties"));
		} catch (IOException e) {
			log.error(e);
			return;
		}
		timeout = Integer.valueOf( properties.getProperty( "timeout", "2000"));
	}
	
	public static synchronized JobsKeeper getInstance( ) {
		return _instance;
	}

	public synchronized void insertJob( final ServerJob job) {
		timeline.put( job.getJobId( ), System.currentTimeMillis( ));
		jobs.add(job);
		log.info( String.format( "WAITING: Job with id: %s submitted to wait for response", job.getJobId( )));
	}
	
	public synchronized void deleteJob( int jobId) {
		for ( Iterator<ServerJob> it = jobs.iterator(); it.hasNext();) {
			ServerJob $ = it.next( );
			if ( $.getJobId( ) == jobId) {
				it.remove( );
				log.info( String.format( "FINISHED: Job with id: %s executed %s time.", jobId, System.currentTimeMillis() - timeline.get(Integer.valueOf( jobId))));
				timeline.remove( Integer.valueOf( jobId));				
				return;
			}
		}
	}
	
	public synchronized List<ServerJob> findOutdated( ) {
		log.info( "Looking for outdated jobs.");
		List<ServerJob> result = new ArrayList<ServerJob>( );
		for( Iterator<ServerJob> it = jobs.iterator(); it.hasNext();) {
			ServerJob $ = it.next( );
			Long delta = System.currentTimeMillis( ) - timeline.get($.getJobId( ));
			if ( delta >= timeout) {
				result.add( $);
				it.remove( );
				timeline.remove( $.getJobId( ));
			}
		}
		log.info( "Found " + result.size( ) + " outdated jobs.");
		return result;
	}
}